home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™94 / Talks & Papers / Michael D. Crawford↵ / Word Services SDK 1.0.5 / Writeswell Jr. Source / TestBed.c < prev    next >
C/C++ Source or Header  |  1993-03-17  |  14KB  |  713 lines

  1. /* TestBed.c
  2.  * Word Services Testbed - main module for Writeswell Jr.
  3.  *
  4.  * ©1992 Working Software, Inc.
  5.  * This source code is copyrighted.  Permission is granted to use the Word Services
  6.  * portion of the Writeswell Jr. source code in your own programs, but you 
  7.  * may not distribute the Writeswell Jr. word-processor code as a 
  8.  * commercial product.  If you modify the code, please do not call it 
  9.  * Writeswell Jr. (or Writeswell.)  This will ensure that people understand the 
  10.  * program and don’t have to deal with a number of different versions with 
  11.  * who-knows-what going on in the code.
  12.  * 
  13.  * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
  14. */
  15.  
  16. #include <EPPC.h>
  17. #include <AppleEvents.h>
  18. #include <AEObjects.h>
  19. #include <Printing.h>
  20. #include "AERegistry.h"
  21. #include "WordServices.h"
  22. #include "TestBed.h"
  23. #include "TBConstants.h"
  24. #include "MyFiles.h"
  25. #include "GenHandlers.h"
  26. #include "AppEvents.h"
  27. #include "AEObj.h"
  28. #include "InitMenu.h"
  29. #include "Gripe.h"
  30. #include "Scroll.h"
  31. #include "Prefs.h"
  32. #include "DoChecking.h"
  33. #include "ServiceMgr.h"
  34. #include "ObWind.h"
  35. #include "ObText.h"
  36. #include "ObNull.h"
  37. #include "FontMenu.h"
  38. #include "Options.h"
  39. #include "ServiceDialog.h"
  40. #include "PrintWWJr.h"
  41. #include "UnloadStuff.h"
  42. #include "InitWWJr.h"
  43. #include "MyGestalt.h"
  44. #include "PageSetup.h"
  45. #include "MyTextEdit.h"
  46.  
  47. #define GLOBALS_HERE
  48. #include "TBGlobals.h"
  49. #undef GLOBALS_HERE
  50.  
  51. Boolean DoMouseDown( EventRecord *eventPtr );
  52. Boolean DoMenuCommand( long menuSpot );
  53. Boolean DoAppleMenu( short theItem );
  54. Boolean DoFileMenu( short theItem );
  55. Boolean DoEditMenu( short theItem );
  56. Boolean DoServMenu( short theItem );
  57. Boolean DoKeyDown( long message, short modifiers );
  58. Boolean DoActivateEvt( short modifiers );
  59. Boolean DoUpdateEvt( long message );
  60. void DoAboutMe( void );
  61. Boolean DoOSEvt( EventRecord *eventPtr );
  62. void GrowDocWindow( WindowPtr theWindow, Point where );
  63. void SetTESize( WindowPtr theWindow );
  64. void MyDrawGrowIcon( WindowPtr theWindow );
  65. void DoCloseWindow( void );
  66. void DoQuit( void );
  67. void DoZoom( WindowPtr theWindow, short deskPart );
  68. void ResetWindowParts( WindowPtr theWindow );
  69. pascal void AboutVersionProc( DialogPtr dlg, short item );
  70.  
  71. void main( void )
  72. {
  73.     short foo;
  74.     OSErr    err;
  75.  
  76.     MaxApplZone();
  77.     InitGraf(&thePort);
  78.     InitFonts();
  79.     /* FlushEvents(everyEvent, 0); */
  80.     InitWindows();
  81.     TEInit();
  82.     InitDialogs(0L);
  83.     
  84.     gDocDirty = false;
  85.  
  86.     gAppFileRefNum = CurResFile();
  87.  
  88.     gQuitRequested = false;
  89.     gPrintRequested = false;
  90.  
  91.     if ( !OpenPrefFile() ){
  92.         Gripe( "\pCannot open Writeswell, Jr. Preferences" );
  93.         ExitToShell();
  94.     }
  95.  
  96.     InitCursor();
  97.  
  98.     if ( System7Installed() ){
  99.         err = InitForSystem7();
  100.     }else{
  101.         err = InitForSystem6();
  102.     }
  103.  
  104.     if ( err )
  105.         ExitToShell();
  106.  
  107.     while ( EventLoop() )
  108.         ;
  109. }
  110.  
  111. Boolean EventLoop( void )
  112. {
  113.     EventRecord theEvent;
  114.     
  115.     UnloadStuff();
  116.  
  117.     if ( gPrintRequested ){
  118.         gPrintRequested = false;
  119.         DoPrint();
  120.     }
  121.  
  122.     if ( gQuitRequested ){
  123.         DoQuit();
  124.         return false;            /* We should never reach this statement */
  125.     }
  126.  
  127.     WaitNextEvent( everyEvent, &theEvent, 30, (RgnHandle)NULL );
  128.     
  129.  
  130.     if ( gDocWindow )
  131.         TEIdle( (TEHandle)GetWRefCon( gDocWindow ) );
  132.     
  133.     switch( theEvent.what ){
  134.         case nullEvent:
  135.             DoNullEvent( &theEvent );
  136.             break;
  137.         case mouseDown:
  138.             return DoMouseDown( &theEvent );
  139.             break;
  140.         case mouseUp:
  141.             DoMouseUp();
  142.             break;
  143.         case autoKey:
  144.         case keyDown:
  145.             return DoKeyDown( theEvent.message, theEvent.modifiers );
  146.             break;
  147.         case updateEvt:
  148.             DoUpdateEvt( theEvent.message );
  149.             break;
  150.         case diskEvt:
  151.             DoDiskEvt();
  152.             break;
  153.         case activateEvt:
  154.             DoActivateEvt( theEvent.modifiers );
  155.             break;
  156.         case osEvt:
  157.             DoOSEvt( &theEvent );
  158.             break;
  159.         case kHighLevelEvent:
  160.             DoHighLevelEvent( &theEvent );
  161.             break;
  162.         default:
  163.             /*Gripe("\pGot unknown event type" );*/
  164.             break;    
  165.     }
  166.  
  167.     return true;
  168. }
  169.  
  170. Boolean DoNullEvent( EventRecord *theEventPtr )
  171. {
  172.     /* One could execute some sort of background task here */
  173.  
  174.     return true;
  175. }
  176.  
  177. Boolean DoMouseDown( EventRecord *eventPtr )
  178. {
  179.     WindowPtr        theWindow;
  180.     Boolean            result = true;
  181.     Rect            dragRect;
  182.     TEHandle        textH;
  183.     short            partCode;
  184.     ControlHandle    ctlHdl;
  185.     short            curFile;
  186.     short            deskPart;
  187.     Boolean            shifted;
  188.     
  189.     deskPart = FindWindow( eventPtr->where, &theWindow );
  190.     switch( deskPart ){
  191.         case inDesk:
  192.             break;
  193.         case inMenuBar:
  194.             FixMenuMarks();
  195.             curFile = CurResFile();
  196.             UseResFile( gPrefFileRefNum );        /* Make SICN resource accessible */
  197.             result = DoMenuCommand( MenuSelect( eventPtr->where ) );
  198.             UseResFile( curFile );
  199.             FixMenuMarks();
  200.             break;
  201.         case inSysWindow:
  202.             SystemClick( eventPtr, theWindow );
  203.             break;
  204.         case inContent:
  205.             if ( theWindow != FrontWindow() ){
  206.                 SelectWindow( theWindow );
  207.             } else {
  208.                 GlobalToLocal( &(eventPtr->where) );
  209.                 partCode = FindControl( eventPtr->where, theWindow, &ctlHdl );
  210.                 if ( partCode == 0 ){
  211.                     textH = (TEHandle)GetWRefCon( theWindow );
  212.                     
  213.                     gScrollWindow = theWindow;        /* For use by TrackContentClick */
  214.  
  215.                     /* 1.1.1 MDC We use an intermediate variable rather than just passing
  216.                      * eventPtr->modifiers & shiftKey because this is a two-byte
  217.                      * value, with a bit set in the high byte.  Since a boolean
  218.                      * is a single byte, this resulted in always passing 0, so we
  219.                      * didn't see the shift key.
  220.                      */
  221.  
  222.                     if ( eventPtr->modifiers & shiftKey ){
  223.                         shifted = true;
  224.                     }else{
  225.                         shifted = false;
  226.                     }
  227.                 
  228.                     TEClick( eventPtr->where, 
  229.                             shifted, 
  230.                             textH );
  231.                 }else{
  232.                     DoControl( theWindow, ctlHdl, partCode, eventPtr->where );
  233.                 }
  234.             }
  235.             break;
  236.         case inDrag:
  237.             DragWindow( theWindow, eventPtr->where, &screenBits.bounds );    /* NOT correct but works */
  238.             break;
  239.         case inGrow:
  240.             GrowDocWindow( theWindow, eventPtr->where );
  241.             break;
  242.         case inGoAway:
  243.             if ( TrackGoAway( theWindow, eventPtr->where ))
  244.                 DoCloseWindow();
  245.             break;
  246.         case inZoomIn:
  247.         case inZoomOut:
  248.             if ( TrackBox( theWindow, eventPtr->where, deskPart ) )
  249.                 DoZoom( theWindow, deskPart );
  250.             break;
  251.     }
  252.     return result;
  253. }
  254.  
  255. Boolean DoMenuCommand( long menuSpot )
  256. {
  257.     short theMenu;
  258.     short theItem;
  259.     Boolean result;
  260.         
  261.     theMenu = HiWord( menuSpot );
  262.     
  263.     theItem = LoWord( menuSpot );
  264.     
  265.     switch ( theMenu ){
  266.         case 0:
  267.             result = true;
  268.             break;
  269.         case kAppleMenuID:
  270.             result = DoAppleMenu( theItem );
  271.             break;
  272.         case kFileMenuID:
  273.             result = DoFileMenu( theItem );
  274.             break;
  275.         case kEditMenuID:
  276.             result = DoEditMenu( theItem );
  277.             break;
  278.         case kFontMenuID:
  279.             result = DoFontMenu( theItem );
  280.             break;
  281.         case kStyleMenuID:
  282.             result = DoStyleMenu( theItem );
  283.             break;
  284.         case kServMenuID:
  285.             result = DoServMenu( theItem );
  286.             break;
  287.     }
  288.     
  289.     HiliteMenu( 0 );
  290.     return result;
  291. }
  292.  
  293. Boolean DoAppleMenu( short theItem )
  294. {
  295.     Handle appleHandle;
  296.     Str255 itemName;
  297.     
  298.     switch ( theItem ){
  299.         case kAMAboutMe:
  300.             DoAboutMe();
  301.             break;
  302.         case kAMDash:
  303.             break;
  304.         default:
  305.             appleHandle = GetResource( 'MENU', kAppleMenuID );
  306.             if ( !appleHandle ){
  307.                 Gripe( "\pCannot get handle to apple menu" );
  308.                 return false;
  309.             }
  310.             
  311.             GetItem( appleHandle, theItem, itemName );
  312.             OpenDeskAcc( itemName );
  313.             if ( gDocWindow ){
  314.                 SetPort( gDocWindow );
  315.             }
  316.             break;
  317.     }
  318.     return true;
  319. }
  320.  
  321. Boolean DoFileMenu( short theItem )
  322. {
  323.     switch ( theItem ){
  324.         case kFMNew:
  325.             if ( gDocWindow )
  326.                 return true;
  327.             
  328.             return MakeNewWindow() == noErr;
  329.             break;
  330.         case kFMOpen:
  331.             DoOpenDialog();
  332.             break;
  333.         case kFMClose:
  334.             DoCloseWindow();
  335.             break;
  336.         case kFMSave:
  337.             DoSave();
  338.             break;
  339.         case kFMSaveAs:
  340.             DoSaveAs();                /* 1.1.1 MDC */
  341.             break;
  342.         case kFMPageSetup:
  343.             DoPageSetup();
  344.             break;
  345.         case kFMPrint:
  346.             DoPrint();
  347.             break;
  348.         case kFMQuit:
  349.             DoQuit();
  350.             break;
  351.     }
  352.     
  353.     return true;
  354. }
  355.  
  356. Boolean DoEditMenu( short theItem )
  357. {
  358.     TEHandle textH;
  359.  
  360.     if ( !SystemEdit( theItem - 1 ) ){
  361.         if ( gDocWindow ){
  362.             textH = (TEHandle)GetWRefCon( gDocWindow );
  363.             
  364.             switch( theItem ){
  365.                 case kEMCut:
  366.                     gDocDirty = true;
  367.                     TECut( textH );
  368.                     break;
  369.                 case kEMCopy:
  370.                     TECopy( textH );
  371.                     break;
  372.                 case kEMPaste:
  373.                     gDocDirty = true;
  374.                     TEStylPaste( textH );
  375.                     break;
  376.                 case kEMClear:
  377.                     gDocDirty = true;
  378.                     TEDelete( textH );
  379.                     break;
  380.                 case kEMOptions:
  381.                     OptionsDialog();
  382.                     break;
  383.             }
  384.             
  385.             SetVertScroll( gDocWindow, gVertScroll );
  386.         }else{
  387.             /* Handle the operations that we can do while the window is closed */
  388.             switch( theItem ){
  389.                 case kEMOptions:
  390.                     OptionsDialog();
  391.                     break;
  392.             }
  393.         
  394.         }
  395.     }
  396.     return true;
  397. }
  398.  
  399. Boolean DoServMenu( short theItem )
  400. {
  401.     OSErr err;
  402.  
  403.     switch( theItem ){
  404. #ifdef NEVER                /* This will return in a future version */
  405.         case kSMCheckSel:
  406.             ToggleSelectCheck();
  407.             break;
  408. #endif
  409.         case kSMNewBatch:
  410.             err = GetNewBatchService();
  411.             if ( err )
  412.                 Gripe( "\pGetNewBatchService failed" );
  413.             break;
  414. #ifdef NEVER                /* This will return in a future version */
  415.         case kSMNewInteractive:
  416.             if ( !gDocWindow )
  417.                 return true;
  418.             break;
  419. #endif
  420.         case kSMRemoveService:
  421.             RemoveServices();
  422.             break;
  423. #ifdef NEVER                /* This will return in a future version */
  424.         case kSMCheckWord:
  425.             if ( !gDocWindow )
  426.                 return true;
  427.             break;
  428. #endif
  429.         case kSMDash:
  430.             break;
  431.         default:
  432.             /* Here is where we actually do some spellchecking! */
  433.             if ( !gDocWindow )
  434.                 return true;
  435.             
  436.             DoSpellCheck( theItem - kSMDash );
  437.             
  438.             break;
  439.     }
  440.     return true;
  441. }
  442.     
  443. Boolean DoMouseUp( void )
  444. {
  445.     return true;
  446. }
  447.  
  448. Boolean DoKeyDown( long message, short modifiers )
  449. {
  450.     char        theChar;
  451.     Boolean        result;
  452.     
  453.     theChar = message & charCodeMask;
  454.     
  455.     if ( modifiers & cmdKey ){
  456.         FixMenuMarks();        /* We need to have the dis/enabling up to date */
  457.         result = DoMenuCommand( MenuKey( theChar ) );
  458.     }else {
  459.         if ( gDocWindow && ( gDocWindow == FrontWindow() )){
  460.             gDocDirty = true;
  461.  
  462.             /* 1.0.3 We need to look for various special cases to
  463.              * tell if we need to scroll.
  464.              */
  465.  
  466.             MyTEKey( gDocWindow, gVertScroll, theChar, false );
  467.         }
  468.         result = true;
  469.     }
  470.         
  471.     return result;
  472. }
  473.  
  474. Boolean DoUpdateEvt( long message )
  475. {
  476.     GrafPtr    curPort;
  477.     
  478.     BeginUpdate( (WindowPtr)message );
  479.     
  480.     if ( (WindowPtr)message == gDocWindow ){
  481.         GetPort( &curPort );
  482.         SetPort( gDocWindow );
  483.         EraseRect( &( thePort->portRect ) );
  484.         TEUpdate( &( thePort->portRect ), (TEHandle)GetWRefCon( (WindowPtr)message ) );
  485.         MyDrawGrowIcon( (WindowPtr)message );
  486.         DrawControls( gDocWindow );
  487.         SetPort( curPort );
  488.     }
  489.  
  490.     EndUpdate( (WindowPtr)message );
  491.     return true;
  492. }
  493.  
  494. void MyDrawGrowIcon( WindowPtr theWindow )
  495. {
  496.     RgnHandle    clipRgn;
  497.     Rect        newClip;
  498.     
  499.     /* This will fudge the DrawGrowIcon routine so we only draw the outline for the
  500.      * vertical scroll bar.  It's easier than writing a custom WDEF.
  501.      * We have to set a new clip region because the update region will mask off some
  502.      * of what we might want to draw.
  503.      *
  504.      * thePort must be the window that is getting the icon drawn in it.
  505.      */
  506.  
  507.     clipRgn = NewRgn();
  508.     if ( !clipRgn )
  509.         return;
  510.     
  511.     GetClip( clipRgn );
  512.     
  513.     newClip.top = theWindow->portRect.top;
  514.     newClip.right = theWindow->portRect.right;
  515.     newClip.bottom = theWindow->portRect.bottom;
  516.     newClip.left = newClip.right - 15;
  517.     
  518.     ClipRect( &newClip );
  519.     
  520.     DrawGrowIcon( theWindow );
  521.  
  522.     SetClip( clipRgn );
  523.     
  524.     DisposeRgn( clipRgn );          /* 1.1.1 MDC fix a leak */
  525.     
  526.     return;
  527. }
  528.  
  529. Boolean DoDiskEvt( void )
  530. {
  531.     return true;
  532. }
  533.  
  534. Boolean DoActivateEvt( short modifiers )
  535. {
  536.  
  537.     if ( gDocWindow ){
  538.  
  539.         if ( modifiers & activeFlag ){
  540.             TEActivate( (TEHandle)GetWRefCon( gDocWindow ) );
  541.         } else {
  542.             TEDeactivate( (TEHandle)GetWRefCon( gDocWindow ) );
  543.         }
  544.     }
  545.     return true;
  546. }
  547.  
  548. void GrowDocWindow( WindowPtr theWindow, Point where )
  549. {
  550.     long    newSize;
  551.     short    newWidth;
  552.     short    newHeight;
  553.     GrafPtr    curPort;
  554.     Rect    sizeRect;
  555.     
  556.     SetRect( &sizeRect, 80, 80, 32767, 32767 );
  557.  
  558.     newSize = GrowWindow( theWindow, where, &sizeRect );
  559.     if ( newSize == 0L )
  560.         return;
  561.  
  562.     newWidth = (short) newSize;
  563.     newHeight = (short) ( newSize >> 16 );
  564.     
  565.     GetPort( &curPort );
  566.     SetPort( theWindow );
  567.  
  568.     SizeWindow( theWindow, newWidth, newHeight, true );
  569.  
  570.     ResetWindowParts( theWindow );
  571.  
  572.     SetPort( curPort );
  573.  
  574.     return;
  575. }
  576.  
  577. void ResetWindowParts( WindowPtr theWindow )
  578. {
  579.     GrafPtr    curPort;
  580.  
  581.     /* Resize all of the components of the document window after the window itself
  582.      * has been resized.
  583.      */
  584.  
  585.     GetPort( &curPort );
  586.     SetPort( theWindow );
  587.  
  588.     SetTESize( theWindow );
  589.  
  590.     /* We have to redraw the whole window, since the grow icon, scroll bars, and
  591.      * text rectange have all changed
  592.      */
  593.     
  594.     InvalRect( &( theWindow->portRect ) );
  595.     
  596.     SizeVertScroll();
  597.     SetVertScroll( theWindow, gVertScroll );
  598.     
  599.     SetPort( curPort );
  600.  
  601.     return;
  602. }
  603.  
  604. Boolean DoOSEvt( EventRecord *eventPtr )
  605. {
  606.     Boolean inBackground;
  607.     
  608.     switch ((eventPtr->message >> 24) & 0x0FF) {     /* high byte of message */
  609.         case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  610.             if ( gDocWindow ){
  611.  
  612.                 inBackground = (eventPtr->message & resumeFlag) == 0;
  613.                 if (inBackground) {
  614. #ifdef NEVER        /* Don't use for styled textedit */
  615.                     ZeroScrap();
  616.                     TEToScrap();
  617. #endif
  618.                     if ( gDocWindow ){
  619.                         TEDeactivate( (TEHandle)GetWRefCon( gDocWindow ) );
  620.                     }
  621.                 } else {
  622. #ifdef NEVER        /* Don't use for styled textedit */
  623.                     TEFromScrap();
  624. #endif
  625.                     if ( gDocWindow ){
  626.                         TEActivate( (TEHandle)GetWRefCon( gDocWindow ) );
  627.                     }
  628.                 }
  629.             }
  630.             
  631.         default:
  632.             break;
  633.     }
  634.     return true;
  635. }
  636.  
  637. Boolean DoHighLevelEvent( EventRecord *theEventPtr )
  638. {
  639.     OSErr err;
  640.     
  641.     err = AEProcessAppleEvent( theEventPtr );
  642.  
  643.     if ( err ){
  644.         return true;            /* An error result is OK... */
  645.     }
  646.  
  647.     return true;
  648. }
  649.  
  650. void SetTESize( WindowPtr theWindow )
  651. {
  652.     Rect    txRect;
  653.     TEHandle    hTE;
  654.     short    rectOffset;
  655.     
  656.     GetTERect( &( theWindow->portRect ), &txRect );
  657.     
  658.     hTE = (TEHandle)GetWRefCon( theWindow );
  659.     
  660.     rectOffset = (*hTE)->destRect.top - (*hTE)->viewRect.top;
  661.  
  662.     (*hTE)->viewRect = txRect;
  663.  
  664.     txRect.top += rectOffset;
  665.     txRect.bottom += rectOffset;
  666.  
  667.     (*hTE)->destRect = txRect;
  668.  
  669.     TECalText( hTE );
  670.  
  671.     return;
  672. }
  673.  
  674. void GetTERect( Rect *portRectPtr, Rect *txRectPtr )
  675. {
  676.     /* Return the rect for the textedit field that will fit in the
  677.      * given portRect, allowing for the scroll bar, and a little bit
  678.      * of margin around all the edges.
  679.      */
  680.  
  681.     *txRectPtr = *portRectPtr;
  682.     InsetRect( txRectPtr, kTextInset, kTextInset );
  683.     
  684.     txRectPtr->right -= 16;
  685.  
  686.     return;
  687. }
  688.  
  689. void DoQuit( void )
  690. {
  691.     if ( gDocWindow )
  692.         DoCloseWindow();
  693.     ExitToShell();
  694.     
  695.     return;
  696. }
  697.  
  698. void DoZoom( WindowPtr theWindow, short deskPart )
  699. {
  700.     Boolean isFront;
  701.     
  702.     if ( FrontWindow() == theWindow )
  703.         isFront = true;
  704.     else
  705.         isFront = false;
  706.  
  707.     ZoomWindow( theWindow, deskPart, isFront );
  708.     
  709.     ResetWindowParts( theWindow );
  710.  
  711.     return;
  712. }
  713.